/*
 * @ProblemId: 
 * @Probtitle: 
 * @Location: 
 * @Author: Morales
 * @Date: 2020-11-26 20:24:16
 * @LastEditTime: 2020-12-11 08:26:50
 * @Space: https://space.bilibili.com/350869102
 * @E-mail: lovexposed@foxmail.com
 * @Blog: https://blog.csdn.net/baidu_41248654
 * @Powered by: Havoc_Wei
 */
#include<bits/stdc++.h>
using namespace std;
typedef int VerTexType;
#define MVNum 100

typedef struct ArcNode{ // 边结点
    int adjvex; // 该边所指向的顶点的位置
    struct ArcNode *nextarc; // 指向下一条边的指针
    // OtheInfo info;
}ArcNode;
typedef struct VNode{ // 顶点信息
    VerTexType data;
    ArcNode *firstarc; // 指向第一条依附该顶点的边的指针
}VNode, AdjList[MVNum];
typedef struct{
    AdjList vertices;
    int vexnum, arcnum; // 图的当前顶点数和边数
}ALGraph;

int LocateVex(ALGraph G, VerTexType v)
{
    for(int i=0; i<G.vexnum; i++)
        if(G.vertices[i].data == v) return i;
    return -1;
}
void CreateUDG(ALGraph &G)
{ // 创建无向图
    cin>>G.vexnum>>G.arcnum;
    for(int i=0; i<G.vexnum; i++)
    {
        cin>>G.vertices[i].data;
        G.vertices[i].firstarc = NULL;
    }
    for(int k=0; k<G.arcnum; k++)
    {
        int v1, v2;
        cin>>v1>>v2;
        int i=LocateVex(G, v1), j=LocateVex(G, v2);
        // 确定v1和v2在G中位置，即顶点在G.vertices中的序号
        ArcNode *p1=new ArcNode, *p2=new ArcNode;
        p1->adjvex = j;
        p1->nextarc = G.vertices[i].firstarc;
        G.vertices[i].firstarc = p1;
        p2->adjvex = i;
        p2->nextarc = G.vertices[j].firstarc;
        G.vertices[j].firstarc = p2;
    }
}
void CreateDG(ALGraph &G)
{ // 创建有向图
    cin>>G.vexnum>>G.arcnum;
    for(int i=0; i<G.vexnum; i++)
    {
        cin>>G.vertices[i].data;
        G.vertices[i].firstarc = NULL;
    }
    for(int k=0; k<G.arcnum; k++)
    {
        int v1, v2;
        cin>>v1>>v2;
        int i=LocateVex(G, v1), j=LocateVex(G, v2);
        // 确定v1和v2在G中位置，即顶点在G.vertices中的序号
        ArcNode *p=new ArcNode;
        p->adjvex = j;
        p->nextarc = G.vertices[i].firstarc;
        G.vertices[i].firstarc = p;
    }
}
void DisplayGraph(ALGraph G)
{ // 输出邻接表
    cout<<G.vexnum<<endl;
    for(int i=0; i<G.vexnum; ++i)
        cout<<G.vertices[i].data<<" ";
    cout<<endl<<G.arcnum<<endl;
    for(int i=0; i<G.vexnum; ++i)
    {
        ArcNode *p = G.vertices[i].firstarc;
        while(p)
        {
            cout<<G.vertices[i].data<<"->"<<G.vertices[p->adjvex].data<<" ";
            p = p->nextarc;
        }
        cout<<endl;
    }
}

int main()
{
    ALGraph G;
    CreateDG(G);
    // CreateUDG(G);
    DisplayGraph(G);
    return 0;
}